﻿using System;
using System.Data.Objects;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using Cjc.Data.Mapping;
using System.Data.Objects.DataClasses;

namespace SampleDataModel.EntityModel
{
	public interface IExposeQueryProvider
	{
		IQueryProvider QueryProvider { get; }
	}

	public class EntityModelMappingContextInfo<TObjectContext> : IMappingContextInfo
		where TObjectContext : ObjectContext, new()
	{
		public ExpressionTranslator CreateExpressionTranslator()
		{
			return new ExpressionTranslator( typeof( TObjectContext ) );
		}

		public object CreateContext( object providerSpecification, TextWriter log )
		{
			return new TObjectContext();
		}

		public IQueryProvider GetQueryProvider( object context )
		{
			return ( context as IExposeQueryProvider ).QueryProvider;
		}

		public void SubmitChanges( object context )
		{
			( context as TObjectContext ).SaveChanges();
		}

		public bool MustInlineInvokes { get { return true; } }

		public Type GetEntityType( string typeName )
		{
			return Type.GetType( typeof( TObjectContext ).Namespace + "." + typeName );
		}

		public Type GetEntityAssociationType( string typeName )
		{
			return typeof( EntityCollection<> ).MakeGenericType( GetEntityType( typeName ) );
		}

		public LambdaExpression GetEntitiesMethod( Type type )
		{
			var context = Expression.Parameter( typeof( TObjectContext ), "oc" );

			return Expression.Lambda( Expression.Property( context, type.Name ), context );
		}

		public virtual LambdaExpression GetXmlMethod( TypeCode typeCode )
		{
			return null;
		}

		public virtual LambdaExpression GetLookupMethod( TypeCode typeCode )
		{
			return null;
		}
	}
}